﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Browser;

namespace Rio.Framework.Pages.Manager
{
    public class QueryByUriManager
    {
        /*
         * Search query pattern
         */

        private const String OrganizationParam = "o";
        private const String FolderTypeParam = "ft";
        private const String FolderParam = "f";
        private const String FolderIdDocParam = "fid";

        /*
         * n-Singleton fields
         */

        //Search
        private static QueryByUriManager _searchInstance;
        public static QueryByUriManager SearchInstance
        {
            get
            {
                return _searchInstance;
            }
        }

        //Import
        private static QueryByUriManager _importInstance;
        public static QueryByUriManager ImportInstance
        {
            get
            {
                return _importInstance;
            }
        }

        /*
         * Properties
         */

        public Uri OrginalUri { get; private set; }

        public long OrganizationId { get; private set; }

        public long FolderTypeId { get; private set; }

        public long FolderId { get; set; }

        public string FolderIdDoc { get; set; }

        public Dictionary<int, string> IndexArgs { get; private set; }

        public QueryByUriSearchAction SearchAction { get; set; }

        /*
         * Methods
         */

        private QueryByUriManager()
        { }

        public static bool Init(Uri searchUri, QueryByUriType queryByUriType)
        {
            //Controls if the uri contains a search in the query
            if (!searchUri.OriginalString.Contains("?"))
                return false;

            string queryString = searchUri.OriginalString.Split('?')[1];

            //Build the query match with the search pattern
            Regex searchPattern = new Regex(String.Format(@"{0}=(\d+)&{1}=(\d+)(&{2}=(\d*))?(&{3}=(\w*))?(&.+)?", OrganizationParam, FolderTypeParam, FolderParam, FolderIdDocParam), RegexOptions.IgnoreCase);
            Match searchMatch = searchPattern.Match(queryString);

            if (!searchMatch.Success)
                return false;

            //Extract OrganizationID
            long organizationId = Int64.Parse(searchMatch.Groups[1].Value);

            //Extract FolderTypeID
            long folderTypeId = Int64.Parse(searchMatch.Groups[2].Value);

            //Extract FolderID
            long folderId = String.IsNullOrWhiteSpace(searchMatch.Groups[4].Value) ? -1 : Int64.Parse(searchMatch.Groups[4].Value);

            //Extract FolderIdDoc
            string folderIdDoc = searchMatch.Groups[6].Value;

            //Extract Indexes
            Regex indexPattern = new Regex(@"&(\d+)=([A-Za-z0-9!""#$%'()*+,./:;<=>?@\^_`\{{|\}}~-]+)+", RegexOptions.IgnoreCase);
            MatchCollection indexMatches = indexPattern.Matches(searchMatch.Groups[7].Value);

            Dictionary<int, string> indexArgs = new Dictionary<int, string>();
            if (indexMatches.Count > 0)
            {
                foreach (Match match in indexMatches)
                {
                    int indexKey = Int32.Parse(match.Groups[1].Value);
                    string indexValue = match.Groups[2].Value;

                    indexArgs.Add(indexKey, HttpUtility.UrlDecode(indexValue));
                }
            }

            //Extract action
            Regex actionRegex = new Regex(@"&action=(\w+)?", RegexOptions.IgnoreCase);
            Match actionMatch = actionRegex.Match(searchMatch.Groups[7].Value);

            QueryByUriSearchAction queryAction = QueryByUriSearchAction.Consultation;
            if (actionMatch.Success)
            {
                string action = actionMatch.Groups[1].Value;
                queryAction = (QueryByUriSearchAction)Enum.Parse(typeof(QueryByUriSearchAction), action, true);
            }

            switch (queryByUriType)
            {
                case QueryByUriType.Search:
                    _searchInstance = new QueryByUriManager
                                          {
                                              FolderTypeId = folderTypeId,
                                              IndexArgs = indexArgs,
                                              OrganizationId = organizationId,
                                              OrginalUri = searchUri,
                                              SearchAction = queryAction,
                                              FolderId = folderId,
                                              FolderIdDoc = folderIdDoc
                                          };
                    break;

                case QueryByUriType.Import:
                    _importInstance = new QueryByUriManager
                                          {
                                              FolderTypeId = folderTypeId,
                                              IndexArgs = indexArgs,
                                              OrganizationId = organizationId,
                                              OrginalUri = searchUri,
                                              SearchAction = QueryByUriSearchAction.None,
                                              FolderId = folderId,
                                              FolderIdDoc = folderIdDoc
                                          };
                    break;
            }

            return true;
        }

        public static void Finish()
        {
            _searchInstance = null;
            _importInstance = null;
        }
    }

    public enum QueryByUriType
    {
        Search,
        Import
    }

    public enum QueryByUriSearchAction
    {
        None,
        Search,
        Consultation,
        SingleConsultation
    }
}
